package com.ayoka.parenting.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.ayoka.parenting.Constants;
import com.ayoka.parenting.base.AppContext;
import com.jincp.common.base.BaseApplication;
import com.jincp.common.utils.AppUtils;
import com.jincp.common.utils.BitmapUtil;
import com.jincp.common.utils.LiveDataBus;
import com.jincp.common.utils.MD5Util;
import com.jincp.common.utils.ToastUtil;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import java.util.Comparator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by jinchunping on 2019/1/24.
 */

public class WeChatManager {

    public static final String TAG = "WeChatManager";

    public static final int WECHAT_NOT_INSTALLED = 0;

    public static final int WECHAT_LOGIN_START = 1;
    public static final int WECHAT_LOGIN_CANCEL = 2;
    public static final int WECHAT_LOGIN_FILED = 3;
    public static final int WECHAT_LOGIN_SUCCESS = 4;

    public static final int WECHAT_SHARE_START = 11;
    public static final int WECHAT_SHARE_CANCEL = 12;
    public static final int WECHAT_SHARE_FILED = 13;
    public static final int WECHAT_SHARE_SUCCESS = 14;

    public static final int WECHAT_PAY_START = 21;
    public static final int WECHAT_PAY_CANCEL = 22;
    public static final int WECHAT_PAY_FILED = 23;
    public static final int WECHAT_PAY_SUCCESS = 24;

    private static final int THUMB_SIZE = 150;

    public static final int WECHAT_SHARE_WAY_TEXT = 1;   //文字
    public static final int WECHAT_SHARE_WAY_PICTURE = 2; //图片
    public static final int WECHAT_SHARE_WAY_WEBPAGE = 3;  //链接
    public static final int WECHAT_SHARE_WAY_VIDEO = 4; //视频
    public static final int WECHAT_SHARE_WAY_MINI_PROGRAM = 5; //小程序
    public static final int WECHAT_SHARE_TYPE_TALK = SendMessageToWX.Req.WXSceneSession;  //会话
    public static final int WECHAT_SHARE_TYPE_FRENDS = SendMessageToWX.Req.WXSceneTimeline; //朋友圈


    private volatile static WeChatManager instance;

    public IWXAPI mWxApi;

    public static WeChatManager getInstance() {
        if (instance == null) {
            synchronized (WeChatManager.class) {
                if (instance == null) {
                    instance = new WeChatManager();
                }
            }
        }
        return instance;
    }

    /**
     * =========================================================
     * @ProjectName:
     * @ClassName: WeChatManager
     * @Description: 该app注册到微信
     * @Description: Constant.WX_APP_ID是指你应用在微信开放平台上的AppID，记得替换。
     * @Author: jincp
     * @CreateDate: 2019/3/14 13:19
     * =========================================================
     */
    private WeChatManager() {
        mWxApi = WXAPIFactory.createWXAPI(AppContext.getInstance(), Constants.WX_APP_ID);
        // 将该app注册到微信
        mWxApi.registerApp(Constants.WX_APP_ID);
    }

    /**
     * =========================================================
     *
     * @ProjectName:
     * @ClassName: WeChatManager
     * @Description: 判断微信是否安装
     * @Author: jincp
     * @CreateDate: 2019/3/14 13:19
     * =========================================================
     */
    public boolean isWXAppInstalled() {
        if (!mWxApi.isWXAppInstalled()) {
            notifyWeChatOperation(WECHAT_NOT_INSTALLED);
            return false;
        }
        return true;
    }

    /**
     * =========================================================
     *
     * @ProjectName:
     * @ClassName: WeChatManager
     * @Description: 开始微信登录
     * @Author: jincp
     * @CreateDate: 2019/3/14 13:18
     * =========================================================
     */
    public void startLogin() {
        if (!isWXAppInstalled()) {
            return;
        }
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_login";
        mWxApi.sendReq(req);

        notifyWeChatOperation(WECHAT_LOGIN_START);
    }

    public void notifyWeChatOperation(int Operation) {
        LiveDataBus.getInstance().with(TAG, Integer.class).postValue(Operation);
    }

    public void startPay(WeChatPayment weChatPayment) {
        if (!isWXAppInstalled()) {
            return;
        }
        PayReq request = new PayReq();
        request.appId = weChatPayment.getAppId();
        request.partnerId = weChatPayment.getPartnerId();
        request.prepayId = weChatPayment.getPrePayId();
        request.packageValue = weChatPayment.getPackageValue();
        request.nonceStr = weChatPayment.getNonceStr();
        request.timeStamp = weChatPayment.getTimeStamp();
        request.sign = weChatPayment.getPaySign();
        mWxApi.sendReq(request);
        notifyWeChatOperation(WECHAT_PAY_START);
    }

    public interface WeChatPayment {

        String getTimeStamp();

        String getPartnerId();

        String getPrePayId();

        String getPaySign();

        String getAppId();

        String getPackageValue();

        String getNonceStr();
    }

    /**
     * =========================================================
     *
     * @ProjectName:
     * @ClassName: WeChatManager
     * @Description: 获取微信二次签名
     * @Author: jincp
     * @CreateDate: 2019/3/14 13:10
     * =========================================================
     */
    public static String getWechatSign(WeChatPayment wechatBean) {
        SortedMap<String, String> signParams = new TreeMap<>(new Comparator<String>() {
            public int compare(String key1, String key2) {
                // 升序排序
                return key1.compareTo(key2);
            }
        });
        signParams.put("appid", wechatBean.getAppId());
        signParams.put("partner_id", wechatBean.getPartnerId());
        signParams.put("noncestr", wechatBean.getNonceStr());
        signParams.put("package", wechatBean.getPackageValue());
        signParams.put("timestamp", wechatBean.getTimeStamp());
        signParams.put("prepayid", wechatBean.getPrePayId());
        String sign = createSign(signParams);
        return sign;
    }

    /**
     * =========================================================
     *
     * @ProjectName:
     * @ClassName: WeChatManager
     * @Description: 微信支付签名算法sign
     * @Author: jincp
     * @CreateDate: 2019/3/14 13:17
     * =========================================================
     */
    @SuppressWarnings("rawtypes")
    private static String createSign(SortedMap<String, String> parameters) {
        StringBuffer mStringBuffer = new StringBuffer();
        // 所有参与传参的参数按照accsii排序（升序）
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (null != value && !"".equals(value) && !"sign".equals(key) && !"key".equals(key)) {
                mStringBuffer.append(key + "=" + value + "&");
            }
        }
        mStringBuffer.append("key=" + Constants.WX_PARENT_APP_KEY); //KEY是商户秘钥
        String sign = MD5Util.encrypt(mStringBuffer.toString()).toUpperCase();
        return sign;
    }

    /**
     * 通过微信分享
     *
     * @param shareContent 分享的方式（文本、图片、链接）
     * @param shareType    分享的类型（朋友圈，会话）
     */
    public void shareByWeChat(ShareContent shareContent, int shareType) {
        switch (shareContent.getShareWay()) {
            case WECHAT_SHARE_WAY_TEXT:
                shareText(shareContent, shareType);
                break;
            case WECHAT_SHARE_WAY_PICTURE:
                sharePicture(shareContent, shareType);
                break;
            case WECHAT_SHARE_WAY_WEBPAGE:
                shareWebPage(shareContent, shareType);
                break;
            case WECHAT_SHARE_WAY_VIDEO:
                shareVideo(shareContent, shareType);
                break;
            case WECHAT_SHARE_WAY_MINI_PROGRAM:
                shareMineProgram(shareContent, shareType);
                break;
        }
    }

    private abstract class ShareContent {

        protected abstract int getShareWay();

        protected abstract String getContent();

        protected abstract String getTitle();

        protected abstract String getURL();

        protected abstract int getPictureResource();
    }

    /**
     * 设置分享文字的内容
     *
     * @author chengcj1
     */
    public class ShareContentText extends ShareContent {
        private String content;

        /**
         * 构造分享文字类
         *
         * @param content 分享的文字内容
         */
        public ShareContentText(String content) {
            this.content = content;
        }

        @Override
        protected int getShareWay() {
            return WECHAT_SHARE_WAY_TEXT;
        }

        @Override
        protected String getContent() {
            return content;
        }

        @Override
        protected String getTitle() {
            return null;
        }

        @Override
        protected String getURL() {
            return null;
        }

        @Override
        protected int getPictureResource() {
            return -1;
        }
    }

    /*
     * 获取文本分享对象
     */
    public ShareContent getShareContentText(String content) {
        ShareContentText mShareContentText = new ShareContentText(content);
        return mShareContentText;
    }

    /**
     * 设置分享图片的内容
     *
     * @author chengcj1
     */
    public class ShareContentPicture extends ShareContent {
        private int pictureResource;

        public ShareContentPicture(int pictureResource) {
            this.pictureResource = pictureResource;
        }

        @Override
        protected int getShareWay() {
            return WECHAT_SHARE_WAY_PICTURE;
        }

        @Override
        protected int getPictureResource() {
            return pictureResource;
        }

        @Override
        protected String getContent() {
            return null;
        }

        @Override
        protected String getTitle() {
            return null;
        }

        @Override
        protected String getURL() {
            return null;
        }
    }

    /*
     * 获取图片分享对象
     */
    public ShareContent getShareContentPicture(int pictureResource) {
        ShareContentPicture  mShareContentPicture = new ShareContentPicture(pictureResource);
        return mShareContentPicture;
    }

    /**
     * 设置分享链接的内容
     *
     * @author chengcj1
     */
    public class ShareContentWebPage extends ShareContent {
        private String title;
        private String content;
        private String url;
        private int pictureResource;

        public ShareContentWebPage(String title, String content, String url, int pictureResource) {
            this.title = title;
            this.content = content;
            this.url = url;
            this.pictureResource = pictureResource;
        }

        @Override
        protected int getShareWay() {
            return WECHAT_SHARE_WAY_WEBPAGE;
        }

        @Override
        protected String getContent() {
            return content;
        }

        @Override
        protected String getTitle() {
            return title;
        }

        @Override
        protected String getURL() {
            return url;
        }

        @Override
        protected int getPictureResource() {
            return pictureResource;
        }
    }

    /*
     * 获取网页分享对象
     */
    public ShareContent getShareContentWebPage(String title, String content, String url, int pictureResource) {
        ShareContentWebPage mShareContentWebPage = new ShareContentWebPage(title, content, url, pictureResource);
        return mShareContentWebPage;
    }

    /**
     * 设置分享视频的内容
     *
     * @author chengcj1
     */
    public class ShareContentVideo extends ShareContent {
        private String url;

        public ShareContentVideo(String url) {
            this.url = url;
        }

        @Override
        protected int getShareWay() {
            return WECHAT_SHARE_WAY_VIDEO;
        }

        @Override
        protected String getContent() {
            return null;
        }

        @Override
        protected String getTitle() {
            return null;
        }

        @Override
        protected String getURL() {
            return url;
        }

        @Override
        protected int getPictureResource() {
            return -1;
        }
    }

    /*
     * 获取视频分享内容
     */
    public ShareContent getShareContentVideo(String url) {
        ShareContentVideo mShareContentVideo = new ShareContentVideo(url);
        return mShareContentVideo;
    }

    /*
     * 分享文字
     */
    private void shareText(ShareContent shareContent, int shareType) {
        String text = shareContent.getContent();
        //初始化一个WXTextObject对象
        WXTextObject textObj = new WXTextObject();
        textObj.text = text;
        //用WXTextObject对象初始化一个WXMediaMessage对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = textObj;
        msg.description = text;
        //构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        //transaction字段用于唯一标识一个请求
        req.transaction = buildTransaction("textshare");
        req.message = msg;
        //发送的目标场景， 可以选择发送到会话 WXSceneSession 或者朋友圈 WXSceneTimeline。 默认发送到会话。
        req.scene = shareType;
        mWxApi.sendReq(req);
    }

    /*
     * 分享图片
     */
    private void sharePicture(ShareContent shareContent, int shareType) {
        Bitmap bitmap = BitmapFactory.decodeResource(AppContext.getInstance().getResources(), shareContent.getPictureResource());
        if (bitmap == null) {
            ToastUtil.getInstance().show("图片不能为空");
            return;
        }
        WXImageObject imgObj = new WXImageObject(bitmap);

        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = imgObj;

        Bitmap thumbBitmap = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
        bitmap.recycle();
        msg.thumbData = BitmapUtil.bitmapToByteArray(thumbBitmap, true);  //设置缩略图

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("imgshareappdata");
        req.message = msg;
        req.scene = shareType;
        mWxApi.sendReq(req);
    }

    /*
     * 分享链接
     */
    private void shareWebPage(ShareContent shareContent, int shareType) {
        WXWebpageObject webpage = new WXWebpageObject();
        webpage.webpageUrl = shareContent.getURL();
        WXMediaMessage msg = new WXMediaMessage(webpage);
        msg.title = shareContent.getTitle();
        msg.description = shareContent.getContent();

        Bitmap bitmap = BitmapFactory.decodeResource(AppContext.getInstance().getResources(), shareContent.getPictureResource());
        if (bitmap == null) {
            ToastUtil.getInstance().show("图片不能为空");
        } else {
            Bitmap thumbBitmap = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
            msg.thumbData = BitmapUtil.bitmapToByteArray(thumbBitmap, true);
            bitmap.recycle();
        }
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("webpage");
        req.message = msg;
        req.scene = shareType;
        mWxApi.sendReq(req);
    }

    /*
     * 分享视频
     */
    private void shareVideo(ShareContent shareContent, int shareType) {
        WXVideoObject video = new WXVideoObject();
        video.videoUrl = shareContent.getURL();

        WXMediaMessage msg = new WXMediaMessage(video);
        msg.title = shareContent.getTitle();
        msg.description = shareContent.getContent();
        Bitmap thumb = AppUtils.getBitmap(BaseApplication.getInstance());
//      BitmapFactory.decodeStream(new_assignment URL(video.videoUrl).openStream());
        /**
         * 测试过程中会出现这种情况，会有个别手机会出现调不起微信客户端的情况。造成这种情况的原因是微信对缩略图的大小、Question、description等参数的大小做了限制，所以有可能是大小超过了默认的范围。
         * 一般情况下缩略图超出比较常见。Title、description都是文本，一般不会超过。
         */
        Bitmap thumbBitmap = Bitmap.createScaledBitmap(thumb, THUMB_SIZE, THUMB_SIZE, true);
        thumb.recycle();
        msg.thumbData = BitmapUtil.bitmapToByteArray(thumbBitmap, true);

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("video");
        req.message = msg;
        req.scene = shareType;
        mWxApi.sendReq(req);
    }

    private String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

    /**
     * 获取网页分享对象
     *
     * @param url           兼容低版本的网页链接
     * @param miniProgramID 小程序原始id
     * @param pages         小程序页面路径
     */
    public ShareContent getShareContenMiniProgram(String title, String content, String url, String miniProgramID, String pages, Bitmap picture) {
        ShareContentMiniProgram mShareContentWebpag = new ShareContentMiniProgram(title, content, url, miniProgramID, pages, picture);
        return mShareContentWebpag;
    }

    /**
     * 设置分享链接的内容
     *
     * @author chengcj1
     */
    public class ShareContentMiniProgram extends ShareContent {
        private String title;
        private String content;
        private String url;
        private String miniProgramID;
        private String pages;
        private Bitmap picture;

        public ShareContentMiniProgram(String title, String content, String url, String miniProgramID, String pages, Bitmap picture) {
            this.title = title;
            this.content = content;
            this.url = url;
            this.miniProgramID = miniProgramID;
            this.pages = pages;
            this.picture = picture;
        }

        @Override
        protected int getShareWay() {
            return WECHAT_SHARE_WAY_MINI_PROGRAM;
        }

        @Override
        protected String getContent() {
            return content;
        }

        @Override
        protected String getTitle() {
            return title;
        }

        @Override
        protected String getURL() {
            return url;
        }

        @Override
        protected int getPictureResource() {
            return 0;
        }

        public Bitmap getPicture() {
            return picture;
        }

        public String getMiniProgramID() {
            return miniProgramID;
        }

        public String getPages() {
            return pages;
        }
    }

    /*
   * 分享小程序
   */
    private void shareMineProgram(ShareContent shareContent, int shareType) {
        WXMiniProgramObject miniProgramObj = new WXMiniProgramObject();
        miniProgramObj.webpageUrl = shareContent.getURL(); // 兼容低版本的网页链接
        miniProgramObj.miniprogramType = WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE;// 正式版:0，测试版:1，体验版:2
        miniProgramObj.userName = ((ShareContentMiniProgram) shareContent).getMiniProgramID();     // 小程序原始id
        miniProgramObj.path = ((ShareContentMiniProgram) shareContent).getPages();            //小程序页面路径
        WXMediaMessage msg = new WXMediaMessage(miniProgramObj);
        msg.title = shareContent.getContent();                    // 小程序消息title
        msg.description = shareContent.getContent();               // 小程序消息desc

        ShareContentMiniProgram miniProgram = (ShareContentMiniProgram) shareContent;
        msg.thumbData = BitmapUtil.bitmapToByteArray(miniProgram.picture, true);  //小程序消息封面图片，小于128k

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("webpage");
        req.message = msg;
        req.scene = SendMessageToWX.Req.WXSceneSession;  // 目前支持会话
        mWxApi.sendReq(req);
    }
}
